package com.topisv.tms.service.work.prepkg;

import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang.StringUtils;
import org.hibernate.ejb.criteria.predicate.ComparisonPredicate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.topisv.tms.entity.Customers;
import com.topisv.tms.entity.User;
import com.topisv.tms.entity.stock.CusStock;
import com.topisv.tms.entity.work.prepkg.PrepkgPlan;
import com.topisv.tms.entity.work.prepkg.PrepkgUpDetail;
import com.topisv.tms.entity.work.prepkg.PrepkgUpItem;
import com.topisv.tms.entity.work.prepkg.PrepkgUpTask;
import com.topisv.tms.repository.CustomersDao;
import com.topisv.tms.repository.UserDao;
import com.topisv.tms.repository.stock.CusStockDao;
import com.topisv.tms.repository.work.prepkg.PrepkgPlanDao;
import com.topisv.tms.repository.work.prepkg.PrepkgUpDetailDao;
import com.topisv.tms.repository.work.prepkg.PrepkgUpItemDao;
import com.topisv.tms.repository.work.prepkg.PrepkgUpTaskDao;

/**
 * 上架任务（预上架流程）_service
 * @author ch
 */
@Component
@Transactional(readOnly = true)
public class PrepkgUpTaskService {

	@Autowired
	private PrepkgUpTaskDao prepkgUpTaskDao;
	@Autowired
	private PrepkgPlanDao prepkgPlanDao;
	@Autowired
	private PrepkgUpItemDao prepkgUpItemDao;
	@Autowired
	private CusStockDao cusStockDao; 
	@Autowired
	private UserDao userDao;
	@Autowired
	private PrepkgUpDetailDao  prepkgUpDetailDao;
	@Autowired
	private CustomersDao customersDao;
	
	/**
	 * 查找任务
	 * @param param 查询参数
	 * @return
	 */
	public List<PrepkgUpTask> loadTaskByParam(Map<String, Object> param) {
		Specification<PrepkgUpTask> spec = getWhereClause(param);
		List<PrepkgUpTask> taskList = this.prepkgUpTaskDao.findAll(spec);
		return taskList;
	}
	
	/**
	 * 查询条件封装
	 * @param param
	 * @return
	 */
	private Specification<PrepkgUpTask> getWhereClause(final Map<String, Object> param) {
		return new Specification<PrepkgUpTask>(){
			@Override
		    public Predicate toPredicate(Root<PrepkgUpTask> r, CriteriaQuery<?> q, CriteriaBuilder cb) {
		      Predicate pre = cb.conjunction();
		      
		      //customerCodes
		      String customerCodes=(String) param.get("customerCodes");
		      if(StringUtils.isNotBlank(customerCodes)) {
		    	  String[] customerCodeSplit = customerCodes.split(":");
				  ComparisonPredicate[] tempCustomerCode = new ComparisonPredicate[customerCodeSplit.length];
				  int i = 0;
				  for (String _customerCode : customerCodeSplit) {
					 tempCustomerCode[i] = (ComparisonPredicate) cb.equal(r.get("customerCode"), _customerCode);
					 i++;
				  }
				  pre.getExpressions().add(cb.or(tempCustomerCode));
		      }
			  
		      //areagroups
		      String areagroups=(String) param.get("areagroups");
		      if(StringUtils.isNotBlank(areagroups)) {
		    	  String[] areagroupSplit = areagroups.split(":");
				  ComparisonPredicate[] areagroupArray = new ComparisonPredicate[areagroupSplit.length];
				  int j = 0;
				  for (String _areagroup : areagroupSplit) {
						areagroupArray[j] = (ComparisonPredicate) cb.equal(r.get("warehouseCode"), _areagroup);
						j++;
				  }
				  pre.getExpressions().add(cb.or(areagroupArray));
			  }
		      
		      Date fromDate= (Date) param.get("fromDate");
		      if (fromDate != null) {
		        pre.getExpressions().add(cb.greaterThanOrEqualTo(r.<Date>get("createTime"), fromDate));
		      }
		      
		      Date toDate= (Date) param.get("toDate");
		      if (toDate != null) {
		        pre.getExpressions().add(cb.lessThanOrEqualTo(r.<Date>get("createTime"), toDate));
		      }
		      
		      String status=(String) param.get("status"); 
		      if(StringUtils.isNotBlank(status)){
		    	  if(status.equals("myTask")){ //我的上架任务
		    		  pre.getExpressions().add(cb.or(
		    				  cb.equal(r.get("status"),"token"),
		    				  cb.equal(r.get("status"),"doing")
		    				  ));
		    	  }
		    	  else{
		    		  pre.getExpressions().add(cb.equal(r.get("status"),status)); 
		    	  }
			  }
		      
		      String workerUuid=(String) param.get("workerUuid");
		      if(StringUtils.isNotBlank(workerUuid)){
					pre.getExpressions().add(cb.equal(r.get("workerUuid"),workerUuid));
			  }	
		      
		      return pre;
		    }
		  };
       }

	/**
	 * 领取任务
	 * @param taskId 任务ID
	 * @param userId 任务执行人
	 * @throws Exception 
	 */
	@Transactional(readOnly = false,rollbackFor=Exception.class)
	public void takeTask(Long taskId, String jobuuid) throws Exception{
		
		try {
			
			PrepkgUpTask task=this.prepkgUpTaskDao.findOne(taskId);
			if(!"undo".equals(task.getStatus())){
				throw new Exception("任务已经被领取");
			}
			
			//修改上架任务状态
			task.setWorkerUuid(jobuuid);
			task.setStatus("token"); 
			this.prepkgUpTaskDao.save(task);
			
			
			//修改出库单状态
			PrepkgPlan plan=this.prepkgPlanDao.loadByPlanCode(task.getPlanCode());
			plan.setStatus("tokeUpTask"); //tokeUpTask:领取上架任务
			this.prepkgPlanDao.save(plan);
		
		} catch (Exception e) {
			
			throw e;
		}
		
	}

	/**
	 * 查询任务
	 * @param taskId
	 * @return
	 */
	public PrepkgUpTask loadTaskById(Long taskId) {
		PrepkgUpTask task=this.prepkgUpTaskDao.findOne(taskId);
		return task;
	}

	/**
	 * 完成上架任务
	 * @param taskId
	 * @throws Exception 
	 */
	@Transactional(readOnly = false,rollbackFor=Exception.class)
	public void completeTask(Long taskId) throws Exception {
		try {
			//修改上架任务状态
			PrepkgUpTask task=this.prepkgUpTaskDao.findOne(taskId);
			task.setStatus("finish");
			this.prepkgUpTaskDao.save(task);
			
			//修改计划状态
			PrepkgPlan plan=this.prepkgPlanDao.loadByPlanCode(task.getPlanCode());
			plan.setStatus("finish"); //状态 （finish:完成预包装计划所有任务 )
			this.prepkgPlanDao.save(plan);
			
		} catch (Exception e) {
			
			throw e;
		}
	}

	/**
	 * 上架
	 * @param taskCode
	 * @param sku
	 * @param stockCode
	 * @param boxCode
	 * @return
	 * @throws Exception 
	 */
	@Transactional(readOnly = false,rollbackFor=Exception.class)
	public String up(String taskCode, String sku,Integer num, Integer weight,String stockCode,String boxCode,String jobuuid) throws Exception {
	    try {
	    	
	    	PrepkgUpTask task=this.prepkgUpTaskDao.loadByTaskCode(taskCode);
	    	String customerCode=task.getCustomerCode();
	    	String warehouseCode=task.getWarehouseCode();
	    	String planCode=task.getPlanCode();
	    	String msg="success_continue";
	    	
	    	if("finish".equals(task.getStatus())){
	    		return "error_finished"; //任务已经完成
	    	}else{
	    		//修改上架任务状态
				task.setStatus("doing");
				this.prepkgUpTaskDao.save(task);
	    	}
	    	
	    	PrepkgUpItem upItem=this.prepkgUpItemDao.loadByTaskCodeAndSku(taskCode,sku);
	    	if(upItem==null){
	    		return "error_sku"; //sku不属于该任务
	    	}
	    	
	    	int temp_num=upItem.getNum()-upItem.getUpNum();
	    	if(temp_num<num){
	    		return "error_num"; //num大于该任务
	    	}
	    	
	    	CusStock stock=this.cusStockDao.loadStock(customerCode, warehouseCode, stockCode, boxCode, sku);
	    	Date now=new Date();
	    	User user=this.userDao.findByJobuuid(jobuuid);
	    	
	    	if(stock!=null){ //箱子存在
	    		
	    		String boxType=stock.getBoxType();
		    	if(!"prepkg".equals(boxType)){
		    		return "error_boxCode"; //箱条码已存放了未包装的商品
		    	}else{
		    		stock.setSalesNum(stock.getSalesNum()+num);
		    	}
		    	
	    	}else{ //箱子不存在
	    		
	    		//修改库存信息
	    		stock=new CusStock();
	    		stock.setAirNum(0);
	    		stock.setBoxCode(boxCode);
	    		stock.setBoxType("prepkg");
	    		stock.setCustomerCode(customerCode);
	    		stock.setLastmodifyTime(now);
	    		stock.setLastopetator(user);
	    		stock.setLockedNum(0);
	    		stock.setOrderNum(0);
	    		stock.setSalesNum(num);
	    		stock.setSku(sku);
	    		stock.setStockCode(stockCode);
	    		stock.setTransportNum(0);
	    		stock.setUnusedNum(0);
	    		stock.setWarehouseCode(warehouseCode);
	    		stock.setBoxType("prepkg");
	    		Customers customer=this.customersDao.findByCustomerCode(customerCode);
	    		stock.setCustomer(customer);
	    		this.cusStockDao.save(stock);
	    		
	    		//修改上架任务明细
	    		Integer upNum_temp=upItem.getUpNum()+num;
	    		upItem.setUpNum(upNum_temp);
	    		
	    		if(upNum_temp<upItem.getNum()){
	    			upItem.setStatus("upping");
	    		}else if(upNum_temp.intValue()==upItem.getNum()){
	    			upItem.setStatus("upped");
	    			//检查整个上架任务是否完成
	    			List<PrepkgUpItem> unuppedList=this.prepkgUpItemDao.loadUnuppedItem(taskCode);
	    			if(unuppedList.size()==0){ //上架任务完成
	    				//修改上架任务状态
	    				task.setStatus("finish");
	    				this.prepkgUpTaskDao.save(task);
	    				//修改预包装计划状态
	    				PrepkgPlan plan=this.prepkgPlanDao.loadByPlanCode(task.getPlanCode());
	    				plan.setStatus("finish");
	    				this.prepkgPlanDao.save(plan);
	    				msg="success_finish";
	    			}
	    			
	    		} 
	    		
	    	}
	    	
	    	//添加上架记录
    		PrepkgUpDetail upDetail=new PrepkgUpDetail();
    		upDetail.setBoxCode(boxCode);
    		upDetail.setCustomerCode(customerCode);
    		upDetail.setNum(num);
    		upDetail.setPlanCode(planCode);
    		upDetail.setSku(sku);
    		upDetail.setStockCode(stockCode);
    		upDetail.setTaskCode(taskCode);
    		upDetail.setWarehouseCode(warehouseCode);
    		upDetail.setWeight(weight);
    		this.prepkgUpDetailDao.save(upDetail);
	    	
	    	return msg;
			
		} catch (Exception e) {
			throw e;
		}
	}

}